{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "from dfply import *"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Case #1: A custom pipe function\n",
    "---\n",
    "\n",
    "Pandas has a function `pd.crosstab` which can generate a cross-tabluation of factors. Let's say we wanted to build a pipe function that wrapped around this. The docstring of the Pandas function is below:\n",
    "\n",
    "Compute a simple cross-tabulation of two (or more) factors. By default\n",
    "computes a frequency table of the factors unless an array of values and an\n",
    "aggregation function are passed\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    index : array-like, Series, or list of arrays/Series\n",
    "        Values to group by in the rows\n",
    "    columns : array-like, Series, or list of arrays/Series\n",
    "        Values to group by in the columns\n",
    "    values : array-like, optional\n",
    "        Array of values to aggregate according to the factors.\n",
    "        Requires `aggfunc` be specified.\n",
    "    aggfunc : function, optional\n",
    "        If specified, requires `values` be specified as well\n",
    "    rownames : sequence, default None\n",
    "        If passed, must match number of row arrays passed\n",
    "    colnames : sequence, default None\n",
    "        If passed, must match number of column arrays passed\n",
    "    margins : boolean, default False\n",
    "        Add row/column margins (subtotals)\n",
    "    dropna : boolean, default True\n",
    "        Do not include columns whose entries are all NaN\n",
    "    normalize : boolean, {'all', 'index', 'columns'}, or {0,1}, default False\n",
    "        Normalize by dividing all values by the sum of values.\n",
    "\n",
    "        - If passed 'all' or `True`, will normalize over all values.\n",
    "        - If passed 'index' will normalize over each row.\n",
    "        - If passed 'columns' will normalize over each column.\n",
    "        - If margins is `True`, will also normalize margin values.\n",
    "        \n",
    "\n",
    "**To keep it simple, let's build a reduced version of this that takes only:**\n",
    "- `index`\n",
    "- `columns`\n",
    "- `values`\n",
    "- `aggfunc`\n",
    "\n",
    "Below is a function that wraps around the call to `pd.crosstab`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def crosstab(index, columns, values=None, aggfunc=None):\n",
    "    return pd.crosstab(index, columns, values=values, aggfunc=aggfunc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>carat</th>\n",
       "      <th>cut</th>\n",
       "      <th>color</th>\n",
       "      <th>clarity</th>\n",
       "      <th>depth</th>\n",
       "      <th>table</th>\n",
       "      <th>price</th>\n",
       "      <th>x</th>\n",
       "      <th>y</th>\n",
       "      <th>z</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0.23</td>\n",
       "      <td>Ideal</td>\n",
       "      <td>E</td>\n",
       "      <td>SI2</td>\n",
       "      <td>61.5</td>\n",
       "      <td>55.0</td>\n",
       "      <td>326</td>\n",
       "      <td>3.95</td>\n",
       "      <td>3.98</td>\n",
       "      <td>2.43</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0.21</td>\n",
       "      <td>Premium</td>\n",
       "      <td>E</td>\n",
       "      <td>SI1</td>\n",
       "      <td>59.8</td>\n",
       "      <td>61.0</td>\n",
       "      <td>326</td>\n",
       "      <td>3.89</td>\n",
       "      <td>3.84</td>\n",
       "      <td>2.31</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   carat      cut color clarity  depth  table  price     x     y     z\n",
       "0   0.23    Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43\n",
       "1   0.21  Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamonds.head(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>color</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>J</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cut</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Fair</th>\n",
       "      <td>163</td>\n",
       "      <td>224</td>\n",
       "      <td>312</td>\n",
       "      <td>314</td>\n",
       "      <td>303</td>\n",
       "      <td>175</td>\n",
       "      <td>119</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Good</th>\n",
       "      <td>662</td>\n",
       "      <td>933</td>\n",
       "      <td>909</td>\n",
       "      <td>871</td>\n",
       "      <td>702</td>\n",
       "      <td>522</td>\n",
       "      <td>307</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Ideal</th>\n",
       "      <td>2834</td>\n",
       "      <td>3903</td>\n",
       "      <td>3826</td>\n",
       "      <td>4884</td>\n",
       "      <td>3115</td>\n",
       "      <td>2093</td>\n",
       "      <td>896</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Premium</th>\n",
       "      <td>1603</td>\n",
       "      <td>2337</td>\n",
       "      <td>2331</td>\n",
       "      <td>2924</td>\n",
       "      <td>2360</td>\n",
       "      <td>1428</td>\n",
       "      <td>808</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Very Good</th>\n",
       "      <td>1513</td>\n",
       "      <td>2400</td>\n",
       "      <td>2164</td>\n",
       "      <td>2299</td>\n",
       "      <td>1824</td>\n",
       "      <td>1204</td>\n",
       "      <td>678</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "color         D     E     F     G     H     I    J\n",
       "cut                                               \n",
       "Fair        163   224   312   314   303   175  119\n",
       "Good        662   933   909   871   702   522  307\n",
       "Ideal      2834  3903  3826  4884  3115  2093  896\n",
       "Premium    1603  2337  2331  2924  2360  1428  808\n",
       "Very Good  1513  2400  2164  2299  1824  1204  678"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "crosstab(diamonds.cut, diamonds.color)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want your function to be part of a dfply pipe chain, the first argument _must_ be a dataframe, which is implicitly passed through during the evaluation of the chain! We will need to redefine the function to have the implicit `df` passed in as the first argument.\n",
    "\n",
    "The most common and straightforward way to convert a custom function to a dfply piping function is to use the `@dfpipe` decorator. \n",
    "\n",
    "> Note: the `@dfpipe` decorator is in fact a convenience decorator that stacks three dfply decorators together: \n",
    "\n",
    "> `@pipe`  \n",
    "`@group_delegation`  \n",
    "`@symbolic_evaluation`  \n",
    "\n",
    "> `@pipe` ensures that the function will work in the dfply piping syntax and take an implicit DataFrame, `@group_delegation` makes the function work with groupings applied prior in the chain, and `@symbolic_evaluation` enables you to use and evaluate symbolic arguments like `X.cut` that are placeholders for incoming data."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "@dfpipe\n",
    "def crosstab(df, index, columns, values=None, aggfunc=None):\n",
    "    return pd.crosstab(index, columns, values=values, aggfunc=aggfunc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th>color</th>\n",
       "      <th>D</th>\n",
       "      <th>E</th>\n",
       "      <th>F</th>\n",
       "      <th>G</th>\n",
       "      <th>H</th>\n",
       "      <th>I</th>\n",
       "      <th>J</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>cut</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>Fair</th>\n",
       "      <td>163</td>\n",
       "      <td>224</td>\n",
       "      <td>312</td>\n",
       "      <td>314</td>\n",
       "      <td>303</td>\n",
       "      <td>175</td>\n",
       "      <td>119</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Good</th>\n",
       "      <td>662</td>\n",
       "      <td>933</td>\n",
       "      <td>909</td>\n",
       "      <td>871</td>\n",
       "      <td>702</td>\n",
       "      <td>522</td>\n",
       "      <td>307</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Ideal</th>\n",
       "      <td>2834</td>\n",
       "      <td>3903</td>\n",
       "      <td>3826</td>\n",
       "      <td>4884</td>\n",
       "      <td>3115</td>\n",
       "      <td>2093</td>\n",
       "      <td>896</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Premium</th>\n",
       "      <td>1603</td>\n",
       "      <td>2337</td>\n",
       "      <td>2331</td>\n",
       "      <td>2924</td>\n",
       "      <td>2360</td>\n",
       "      <td>1428</td>\n",
       "      <td>808</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>Very Good</th>\n",
       "      <td>1513</td>\n",
       "      <td>2400</td>\n",
       "      <td>2164</td>\n",
       "      <td>2299</td>\n",
       "      <td>1824</td>\n",
       "      <td>1204</td>\n",
       "      <td>678</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "color         D     E     F     G     H     I    J\n",
       "cut                                               \n",
       "Fair        163   224   312   314   303   175  119\n",
       "Good        662   933   909   871   702   522  307\n",
       "Ideal      2834  3903  3826  4884  3115  2093  896\n",
       "Premium    1603  2337  2331  2924  2360  1428  808\n",
       "Very Good  1513  2400  2164  2299  1824  1204  678"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "diamonds >> crosstab(X.cut, X.color)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Case #2: A function that works with symbolic arguments\n",
    "---\n",
    "\n",
    "Many tasks are simpler and do not require the capacity to work as a pipe function. The `dfply` window functions are the common examples of this: functions that take a Series (or _symbolic_ Series) and return a modified version.\n",
    "\n",
    "Let's say we had a dataframe with dates represented by strings that we wanted to convert to pandas datetime objects using the `pd.to_datetime` function. Below is a tiny example dataframe with this issue."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>sales</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7/10/17</td>\n",
       "      <td>1220</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>7/11/17</td>\n",
       "      <td>1592</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7/12/17</td>\n",
       "      <td>908</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7/13/17</td>\n",
       "      <td>1102</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7/14/17</td>\n",
       "      <td>1395</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      date  sales\n",
       "0  7/10/17   1220\n",
       "1  7/11/17   1592\n",
       "2  7/12/17    908\n",
       "3  7/13/17   1102\n",
       "4  7/14/17   1395"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sales = pd.DataFrame(dict(date=['7/10/17','7/11/17','7/12/17','7/13/17','7/14/17'],\n",
    "                          sales=[1220, 1592, 908, 1102, 1395]))\n",
    "sales"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "date     object\n",
       "sales     int64\n",
       "dtype: object"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sales.dtypes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In pandas we would use the `pd.to_datetime` function to convert the strings to date objects, and add it as a new column like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>sales</th>\n",
       "      <th>pd_date</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7/10/17</td>\n",
       "      <td>1220</td>\n",
       "      <td>2017-07-10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>7/11/17</td>\n",
       "      <td>1592</td>\n",
       "      <td>2017-07-11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7/12/17</td>\n",
       "      <td>908</td>\n",
       "      <td>2017-07-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7/13/17</td>\n",
       "      <td>1102</td>\n",
       "      <td>2017-07-13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7/14/17</td>\n",
       "      <td>1395</td>\n",
       "      <td>2017-07-14</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      date  sales    pd_date\n",
       "0  7/10/17   1220 2017-07-10\n",
       "1  7/11/17   1592 2017-07-11\n",
       "2  7/12/17    908 2017-07-12\n",
       "3  7/13/17   1102 2017-07-13\n",
       "4  7/14/17   1395 2017-07-14"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sales['pd_date'] = pd.to_datetime(sales['date'], infer_datetime_format=True)\n",
    "sales"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "sales.drop('pd_date', axis=1, inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What if you tried to use the `pd.to_datetime` function inside of a call to mutate, like so?\n",
    "\n",
    "```python\n",
    "sales >> mutate(pd_date=pd.to_datetime(X.date, infer_datetime_format=True))\n",
    "```\n",
    "\n",
    "This will unfortunately break. The `dfply` functions are special in that they \"know\" to delay their evaluation until the data is at that point in the chain. `pd.to_datetime` is not such a function, and will immediately try to evaluate `X.date`. With a symbolic `Intention` argument passed in, the function will fail as it does not know what to do with that.\n",
    "\n",
    "Instead, we will need to make a wrapper around `pd.to_datetime` that can handle these symbolic arguments and delay evaluation until the right time. \n",
    "\n",
    "This is quite simple: all you need to do is decorate a function with the `@make_symbolic` decorator, like so:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "@make_symbolic\n",
    "def to_datetime(series, infer_datetime_format=True):\n",
    "    return pd.to_datetime(series, infer_datetime_format=infer_datetime_format)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style>\n",
       "    .dataframe thead tr:only-child th {\n",
       "        text-align: right;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: left;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>date</th>\n",
       "      <th>sales</th>\n",
       "      <th>pd_date</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7/10/17</td>\n",
       "      <td>1220</td>\n",
       "      <td>2017-07-10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>7/11/17</td>\n",
       "      <td>1592</td>\n",
       "      <td>2017-07-11</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7/12/17</td>\n",
       "      <td>908</td>\n",
       "      <td>2017-07-12</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>7/13/17</td>\n",
       "      <td>1102</td>\n",
       "      <td>2017-07-13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>7/14/17</td>\n",
       "      <td>1395</td>\n",
       "      <td>2017-07-14</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      date  sales    pd_date\n",
       "0  7/10/17   1220 2017-07-10\n",
       "1  7/11/17   1592 2017-07-11\n",
       "2  7/12/17    908 2017-07-12\n",
       "3  7/13/17   1102 2017-07-13\n",
       "4  7/14/17   1395 2017-07-14"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sales >> mutate(pd_date=to_datetime(X.date))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And there you go. Able to delay the evaluation.\n",
    "\n",
    "What's particularly nice about the `@make_symbolic` decorator is that it has no trouble working with non-symbolic arguments too. If we were to pass in the series itself the function evaluates without a problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2017-07-10\n",
       "1   2017-07-11\n",
       "2   2017-07-12\n",
       "3   2017-07-13\n",
       "4   2017-07-14\n",
       "Name: date, dtype: datetime64[ns]"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "to_datetime(sales.date)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Keep in mind, though, that if _any_ of the arguments or keyword arguments are symbolic `Intention` objects, the return will itself be an `Intention` object representing the function awaiting evaluation by a dataframe:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<dfply.base.Intention at 0x1199570f0>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "to_datetime(X.date)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0   2017-07-10\n",
       "1   2017-07-11\n",
       "2   2017-07-12\n",
       "3   2017-07-13\n",
       "4   2017-07-14\n",
       "Name: date, dtype: datetime64[ns]"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "awaiting = to_datetime(X.date)\n",
    "awaiting.evaluate(sales)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
